package com.itcodai.utils.stream;

import java.util.ArrayList;
import java.util.Collections;

/**
 * 集合 流基本用法
 * @author c-fanqj
 * @date 2022/5/11
 * @apiNote
 */
public class BasicStreamExercise {
    public static void main(String[] args) {
        //System.out.println("1111");

        // 1.集合的流式编程
        /*ArrayList<Integer> list = new ArrayList<>();
        // 串行获取数据 #
        Stream<Integer> stream = list.stream();
        // 并行获取数据
        Stream<Integer> stream1 = list.parallelStream();

        int[] array = {1, 2, 3, 4, 5};
        IntStream stream2 = Arrays.stream(array);*/


        // 2.最终操作 【关闭流】

        ArrayList<Integer> list1 = new ArrayList<>();
        Collections.addAll(list1,
                10, 20, 30, 40, 50, 60, 70, 80, 90);
        //System.out.println("list=" + list1);

        // 2.1 collect
        // 转成List
        /*List<Integer> result = list1.stream().collect(Collectors.toList());
        System.out.println(result);
        // 转成Set
        Set<Integer> result1 = list1.stream().collect(Collectors.toSet());
        System.out.println(result1);
        // 参数是转成规则
        //list1.stream().collect(Collectors.toCollection());
        // 参数：键的生成规则    值的生成规则  转成Map
        Map<Integer, Integer> result2 = list1.stream().collect(
                Collectors.toMap(ele -> ele / 10, ele -> ele));
        System.out.println(result2);*/

        // 2.2 reduce 按照一定的规则聚合起来
        // 元素求和
        /*int result3 = list1.stream().reduce((e1, e2) -> e1 + e2).get();
        System.out.println(result3);*/

        // 2.3 count
        /*long result4 = list1.stream().count();
        System.out.println(result4);*/

        // 2.4 forEach
        //list1.stream().forEach(System.out::println);

        // 2.5 max & min
        /*Integer result5 = list1.stream().max(Integer::compareTo).get();
        System.out.println("max is:" + result5);
        Integer result6 = list1.stream().min(Integer::compareTo).get();
        System.out.println("min is:" + result6);*/

        // 2.6 Matching
        // allMatch：都满足，为true
        /*boolean result7 = list1.stream().allMatch(ele -> ele > 50);
        System.out.println(result7);
        // anyMatch：存在满足 为true
        boolean result8 = list1.stream().anyMatch(ele -> ele > 50);
        System.out.println(result8);
        // noneMatch：都不满足 为true
        boolean result9 = list1.stream().noneMatch(ele -> ele % 2 != 0);
        System.out.println(result9);*/

        // 2.7 fine:findFirst findAny
        /*Integer result10 = list1.stream().findFirst().get();
        Integer result11 = list1.stream().findAny().get();
        System.out.println(result10 + "===" + result11);*/

        /*Integer result12 = list1.parallelStream().findFirst().get();
        Integer result13 = list1.parallelStream().findAny().get();
        System.out.println(result12 + "===" + result13);*/

        /*Stream<Integer> steam = list1.stream();
        long count1 = steam.count(); // 关闭流
        System.out.println(count1);
        steam.forEach(System.out::println);*/

        /*Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
        at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
        at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
        at com.itcodai.util.stream.BasicStreamExercise.main(BasicStreamExercise.java:90)*/


        // 3.中间操作 【返回流】
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2,
                "hello", "world", "java", "hadoop", "qianfeng", "goodprogrammer", "niubi");
        // 3.1 filter 条件过滤
        //list2.stream().filter(ele->ele.length()>5).forEach(System.out::println);

        // 3.2 distinct 去重
        /*list2.add("hello");
        list2.add("java");
        System.out.println(list2);
        list2.stream().distinct().forEach(System.out::println);*/

        // 3.3 sorted 排序
        //list2.stream().sorted().forEach(System.out::println);
        // 自定义排序规则
        //list2.stream().sorted((e1,e2)->e1.length()-e2.length()).forEach(System.out::println);

        // 3.4 limit & skip
        // skip 跳过
        //list2.stream().skip(3).forEach(System.out::println);
        // limit 截取
        //list2.stream().limit(4).forEach(System.out::println);
        //list2.stream().skip(5).limit(2).forEach(System.out::println);

        // 3.5 map & flatMap   映射，替换
        // map 新的数据替换旧的数据  直接映射
        //list2.stream().map(ele->ele+".txt").forEach(System.out::println);

        String[] strs = {"hello", "world"};
        //Arrays.stream(strs).map(String::toCharArray).forEach(System.out::println);
        // hello world
        /* Arrays.stream(strs).map(String::toCharArray)
                .forEach((ele -> System.out.println(Arrays.toString(ele))));*/
        // [h, e, l, l, o] [w, o, r, l, d]
        // flatMap 扁平化映射
        /*Arrays.stream(strs).map(ele -> ele.split("")).flatMap(Arrays::stream)
                .forEach(System.out::print);*/
        // h e l l o w o r l d

        // 3.6 mapToInt
        ArrayList<Person> list3 = new ArrayList<>();
        Collections.addAll(list3, new Person("xiaoming", 12),
                new Person("laowang", 13), new Person("xiaobai", 11));
        // 求和
        long ages = list3.stream().map(ele -> ele.getAge()).reduce((e1, e2) -> e1 + e2).get();
        long count = list3.stream().count();
        System.out.println("sum---" + ages + " num---" + count + " avg---" + (ages/count));
        //list3.stream().mapToInt(Person::getAge).forEach(System.out::println);
        //double avg = list3.stream().mapToInt(Person::getAge).average().getAsDouble();
        //System.out.println(avg);
    }

    static class Person {
        String name;
        int age;

        public int getAge() {
            return age;
        }

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }

}
